<?php
 /**
 * MYSQL populator
 * 
 * AUTHOR
 * amine.matmati@gmail.com
 *
 * 
 * PURPOSE 
 * populate mysql tables with random data.
 * 
 * 
 * WHY ?
 * Avoid developers borring tasks (copy/paste INSERT INTO queries)..
 * 
 * 
 * HOW DOES IT WORK ?
 * This script simply connects to a MYSQL database, stores tables descriptions 
 * and try to populate em with as mush data as wanted
 * 
 * 
 * IS THERE A LIMIT ?
 * the only limit is the "max_execution_time" option in your php.ini file.
 * you can change it or execute the script in cli mode.
 * 
 * 
 * QUICKSTART : 
 *  1- open file
 *  2- edit mysql database options : server, user, password and database name
 *  3- Provide the number of rows you want your table to have. 
 *  3- Run the file in your browser
 * 
 * DETAILED INSTALLATION AND CONFIGURATION :
 *  if you need one, delete this script and never use it again.
 *  
 * 
 * LIMITS 
 * if you have foreign keys in your tables, this script will probably not work
 * the foreign key support will be implemented in a future release (maybe !)   
 * 
 *  
 * 
 */



/* ---------- OPTIONS TO CHANGE ------------ */
/**
 * Database configuration
 */ 
    
$dbserver = 'localhost'; 
$dbuser = 'root';
$dbpass = '';
$dbname = 'populator';

/**
 * INT : number of rows you want your tables to be populated with 
 */ 
$max_rows = 500000;

/* ---------- NO MORE OPTIONS TO CHANGE ------------ */
/* ---------- JUST EXECUTE IT IN YOUR BROWSER ------------ */



/**
 * CRLF conatant used for echo statements br, /n ... 
 */ 
define('CRLF', '<br />') ;


//database connection 
if (!mysql_connect($dbserver, $dbuser, $dbpass)){
    exit('No database connection, please check your Database configuration');
}

if (!mysql_select_db($dbname)){
    exit('UNABLE to connect to database' . $dbname);
}


$start = microtime(TRUE);

/**
 * array $tables
 * containd table names
 */
  
$tables = getDbTables($dbname);
if (empty($tables)){
    exit('UNABLE to detect your database structure');
}

/**
 * array structures
 * contains the database structure(only needed fields)
 */

 
$structure = array(); 
foreach ($tables as $table){
    $rs = mysql_query('DESCRIBE `' . $table . '`');
    if(!$rs){
        echo 'MYSQL ERROR | FUNCTION : getDbTables | SQL : [' . $sql . '] | ERROR : ['.mysql_error().']' . CRLF;
    }

    while($description = mysql_fetch_assoc($rs)){
        $structure[$table]['fields'][] = $description['Field']; 
        $structure[$table]['types'][] = $description['Type'];
        $structure[$table]['extra'][] = $description['Extra'];  
    }
}  




/**
 * Building insert query for each table
 */ 
 
foreach ($structure as $table_name => $table_structure){
    $values  = array();        
    $columns = array();
    $i = 0;
    $success = 0;
    
    //columns
    foreach ($table_structure['fields'] as $field){        
        $columns[] = '`' . $field . '`'; 
    }        
    $fld = implode(',', $columns);
    
    
    //values
    while ($i < $max_rows){
        $values = array();
        foreach ($table_structure['fields'] as $field_index => $field){
            $values[] = '\'' 
            . getRandValue(
                $table_structure['types'][$field_index],
                $table_structure['extra'][$field_index]
            )             
            . '\'';             
        }
        $val = implode(',', $values);                   
            
        $query = 'INSERT INTO `' . $table_name . '` (' . $fld . ') VALUES (' . $val . ')';
        $result = mysql_query($query);
        if(!$result){
            echo 'MYSQL ERROR SQL : [' . $query . '] | ERROR : [' . mysql_error() . ']' . CRLF;
        }    
        //echo $query . CRLF;
        $i++;
        $succeded++ ;
        unset($values);         
    }

    echo $succeded . ' rows inserted in table ' . strtoupper($table_name) . CRLF;
              
}

/**
 * database structure
 */
echo '<h1> DATABASE STRUCTURE </h1>';
echo '<pre>'; 
print_r($structure);
echo '</pre>';

$end = microtime(TRUE);
echo 'EXEC TIME ' . ($end - $start) ; 
exit('DONE'); 

 
 
 
 
 
/**
 * getRandValue()
 *   
 * @param string $field_type
 * @param string $field_extra
 * @return returns random data according to $field_type
 */
function getRandValue($field_type, $field_extra)
{
    if (!isset($field_type, $field_extra)){
        echo 'ERROR | FUNCTION : getRandValue | ERROR : Invalide params'; 
    }
    
    if ($field_extra == 'auto_increment'){
        return NULL;
    }
    
    
    //determine the data length
    if(count(explode('(', $field_type)) != 2){
        $type = $field_type;
        $length = 255;
    } else {
        list($type, $length) = explode('(', $field_type);
        if (strripos($length,')') == strlen($length)){
            $length = substr($length,0, strlen($length) - 1);
        }        
    }
    

    
    //If we are unable to control data length, we just add a big value.
    //mysql will handle truncating to the correct size.
    switch($type){
        //numeric types
        case 'int':
        case 'tinyint':
        case 'smallint':
        case 'mediumint':
        case 'bigint':
        case 'double':
        case 'decimal':
        case 'float':
        case 'double':
        case 'real':    
        case 'int':                            
            $data = rand(1,99999999);
        break;
        
        case 'bit':
        case 'bool':
            return rand(0,1);
            break;
        
            
        //date/time types
        case ('date'):                
            $data = getRandDate();        
            break;
        
        case 'datetime':
        case 'timestamp':
            $data = getRandDateTime();
            break;
        
        case ('time'):
            $data = getRandTime();
            break;
        
        case('year'):
            $data = getRandYear();
            break;
        
        case('text'):
            $data = getLipsum(1024);
            break;                    

        //Here we can add other types
        
        //Let's just return a random string for now
        default:
            $data = getLipsum(255);
        break;    
    }
    
    //echo 'type = [' . $type . '] data returned ['.$data.']' . CRLF;
    return $data;    
} 



/**
 * getRandDate()
 * 
 * @return random date in mysql format (YYYY-MM-DD)
 */
function getRandDate()
{
    $year = getRandyear();
    $month = rand(01, 12);
    $day = rand(01, 29);
    return $year . '-' . $month . '-' . $day;
}

/**
 * getRandyear()
 * 
 * @return random year between 1970 and current year (YYYY)
 */
function getRandyear()
{
    return rand(1970, date('Y'));
}


/**
 * getRandTime()
 * 
 * @return random time in mysql format(HH:MM:SS)
 */
function getRandTime()
{
    $hour  = rand(00, 23);
    $minute = rand(00, 59);
    $second = rand(00, 59);
    return $hour . ':' . $minute . ':' . $second;
}

/**
 * getRandDateTime()
 * 
 * @return random timestamp in mysql format (YYYY-MM-DD HH:MM:SS)
 */
function getRandDateTime()
{
    return getRandDate() . ' ' . getRandTime(); 
}


/**
 * getDbTables()
 * return tables names
 * @param string $database_name
 * @return array()
 */
function getDbTables($database_name)
{
    $sql = 'SHOW TABLES FROM ' . $database_name . '';
    $result = mysql_query($sql);
    if(!$result){
        echo 'MYSQL ERROR | FUNCTION : getDbTables | SQL : [' . $sql . '] | ERROR : ['.mysql_error().']' . CRLF;
        exit;
    }    
    
    $tables = array();
    while ($row = mysql_fetch_array($result)){
        $tables[] = $row[0];
    }
    return $tables;
}





/**
 * getLipsum()
 * @param int $length
 * @return random texte
 */
function getLipsum($length = 32)
{
    $lipsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Nullam iaculis nibh eget est auctor non facilisis mauris elementum. 
    Vestibulum vel risus lectus, et fringilla urna. Nam egestas malesuada risus cursus tempus. 
    Duis eu tincidunt ligula. Fusce venenatis feugiat dolor, ut rutrum elit interdum ac. 
    Curabitur vitae metus nec enim interdum rutrum. Donec justo eros, dignissim eu viverra laoreet, 
    suscipit eget dolor. Nam non velit ut enim tempus tempus. 
    Phasellus rhoncus leo ut tortor tincidunt sollicitudin. 
    Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; 
    Praesent porttitor laoreet auctor. Integer vitae sem sapien. Mauris mauris nisl, 
    dictum sit amet tristique ac, sagittis nec augue. 
    Aliquam vehicula eros sed felis hendrerit vestibulum. 
    Pellentesque a odio vel massa lobortis cursus et vel mauris. Vestibulum quis ultricies magna.
    consectetur adipiscing elit. 
    Nullam iaculis nibh eget est auctor non facilisis mauris elementum. 
    Vestibulum vel risus lectus, et fringilla urna. Nam egestas malesuada risus cursus tempus. 
    Duis eu tincidunt ligula. Fusce venenatis feugiat dolor, ut rutrum elit interdum ac. 
    Curabitur vitae metus nec enim interdum rutrum. Donec justo eros, dignissim eu viverra laoreet, 
    suscipit eget dolor. Nam non velit ut enim tempus tempus. 
    Phasellus rhoncus leo ut tortor tincidunt sollicitudin. 
    Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; 
    Praesent porttitor laoreet auctor. Integer vitae sem sapien. Mauris mauris nisl, 
    dictum sit amet tristique ac, sagittis nec augue. 
    Aliquam vehicula eros sed felis hendrerit vestibulum. 
    Pellentesque a odio vel massa lobortis cursus et vel mauris. Vestibulum quis ultricies magna.' ;


    if ($length < strlen($lipsum)){
        return substr($lipsum, 0, $length);
    }
    
    return $lipsum;    
}








